// copyright jyz.2024
#include "AuraEnemy.h"
#include "AbilitySystemComponent.h"
#include "AuraCommonFunLibrary.h"
#include "AuraGameplayTags.h"
#include "AuraRPGDemo.h"
#include "AbilitySystem/AuraAbilitySystemComponent.h"
#include "AbilitySystem/AuraAttributeSet.h"
#include "Components/WidgetComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "UI/Widget/AuraUserWidget.h"


AAuraEnemy::AAuraEnemy()
{
	GetMesh()->SetCollisionResponseToChannel(ECC_Visibility,ECR_Block);
	AbilitySystemComponent = CreateDefaultSubobject<UAuraAbilitySystemComponent>("AbilitySystemComponent");
	AbilitySystemComponent->SetIsReplicated(true);
	//AI角色不需要复制GameplayEffects，这些可以在服务器上计算完成后，只需要播放对应的GameCues即可（确保只有最重要GameplayEffects的数据被复制并在网络上发送）
	AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);
	AttributeSet = CreateDefaultSubobject<UAuraAttributeSet>("AttributeSet");
	HealthBarComp = CreateDefaultSubobject<UWidgetComponent>(TEXT("HealthBarComp"));
	HealthBarComp->AttachToComponent(GetRootComponent(),FAttachmentTransformRules::KeepRelativeTransform);
	HealthBarComp->SetWidgetSpace(EWidgetSpace::Screen);
	HealthBarComp->SetDrawAtDesiredSize(true);
	HealthBarComp->SetRelativeLocation(FVector(0,0,60.0));
}

void AAuraEnemy::SetHighlightActor(bool bIsHovered)
{
	GetMesh()->SetCustomDepthStencilValue(bIsHovered ? CUSTOM_DEPTH_RED : 0);
	GetMesh()->SetRenderCustomDepth(bIsHovered);
	Weapon->SetRenderCustomDepth(bIsHovered);
	Weapon->SetCustomDepthStencilValue(bIsHovered ? CUSTOM_DEPTH_RED : 0);
}

int32 AAuraEnemy::GetCharacterLevel() const
{
	return Level;
}

void AAuraEnemy::Die()
{
	SetLifeSpan(LifeSpan);
	Super::Die();
	if(HealthBarComp)
	{
		HealthBarComp->SetHiddenInGame(true);
	}
}

void AAuraEnemy::BeginPlay()
{
	Super::BeginPlay();
	GetCharacterMovement()->MaxWalkSpeed = BaseWalkSpeed;

	//授予敌人能力
	UAuraCommonFunLibrary::GiveStartupAbilities(this,AbilitySystemComponent);
	
	if(UAuraUserWidget*AuraUserWidget = Cast<UAuraUserWidget>(HealthBarComp->GetUserWidgetObject()))
	{
		AuraUserWidget->SetWidgetController(this);
	}
	InitAbilityActorInfo();
	
}

void AAuraEnemy::InitAbilityActorInfo()
{
	AbilitySystemComponent->InitAbilityActorInfo(this,this);
	Cast<UAuraAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();
	Super::InitAbilityActorInfo();

	const UAuraAttributeSet* EnemyAS = CastChecked<UAuraAttributeSet>(AttributeSet);
	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(EnemyAS->GetHealthAttribute())
	.AddLambda([this](const FOnAttributeChangeData& Data)
	{
		OnHealthDelegate.Broadcast(Data.Attribute.GetNumericValue(AttributeSet));
	});
	AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(EnemyAS->GetMaxHealthAttribute())
    .AddLambda([this](const FOnAttributeChangeData& Data)
    {
    	OnMaxHealthDelegate.Broadcast(Data.Attribute.GetNumericValue(AttributeSet));
    });
	AbilitySystemComponent->RegisterGameplayTagEvent(FAuraGameplayTags::Get().Effects_HitReact).AddUObject(this,&AAuraEnemy::OnHitReactChange);
	OnHealthDelegate.Broadcast(EnemyAS->GetHealth());
	OnMaxHealthDelegate.Broadcast(EnemyAS->GetMaxHealth());
}

void AAuraEnemy::InitializeDefaultAttribute()
{
	UAuraCommonFunLibrary::InitializeDefaultAttribute(this,CharacterClass,Level,AbilitySystemComponent);
}

void AAuraEnemy::OnHitReactChange(const FGameplayTag Tag, int32 NewCount)
{
	bHitReacting = NewCount > 0;
	GetCharacterMovement()->MaxWalkSpeed = bHitReacting ? 0 : BaseWalkSpeed;
}

